"""
Case Type   : fullsql
Case Name   : 系统表中transaction_id针对事务中语句的校验
Create At   : 2022/01/28
Owner       : zhao-pengcheng-g
Description :
    1.设置track_stmt_stat_level为'l2,l2'
    2.会话1开启事务,查询txid_current，创建表，插入数据
    3.会话2通过系统表查询transaction_id
    4.环境清理
Expect      :
    1.成功
    2.成功
    3.成功
    4.成功
History     :
"""
import time
import unittest
from yat.test import Node
from yat.test import macro
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger
from testcase.utils.Common import Common
from testcase.utils.ComThread import ComThread


class Fullsql(unittest.TestCase):
    def setUp(self):
        self.logger = Logger()
        text = '---Opengauss_Function_Fullsql_Case0008 start---'
        self.logger.info(text)
        self.userNode = Node('PrimaryDbUser')
        self.sh_primy = CommonSH('PrimaryDbUser')
        self.constant = Constant()
        self.common = Common()
        self.table_name = 'table_fullsql_0008'

    def test_fullsql(self):
        text = "---step1:设置track_stmt_stat_level为'l2,l2',expect:成功---"
        self.logger.info(text)
        self.config_level = 'track_stmt_stat_level'
        self.show_level_cmd = f'show {self.config_level};'
        show_level_res = self.sh_primy.execut_db_sql(self.show_level_cmd)
        self.logger.info(show_level_res)
        self.level_default = show_level_res.splitlines()[-2].strip()
        if 'l2,l2' != self.level_default:
            result = self.sh_primy.execute_gsguc('reload',
                                                 self.constant.GSGUC_SUCCESS_MSG,
                                                 f"{self.config_level}='l2,l2'")
            self.assertTrue(result, '参数修改失败')
        check_level_msg = self.sh_primy.execut_db_sql(self.show_level_cmd)
        self.logger.info(check_level_msg)
        self.common.equal_sql_mdg(check_level_msg, f'{self.config_level}',
                                  'l2,l2', '(1 row)', flag='1')

        text_2 = '---step2:会话1开启事务,查询txid_current，' \
                 '创建表，插入数据，expect:成功---'
        self.logger.info(text_2)
        sql_cmd = f'''set current_schema to public;
                      start transaction;
                      select txid_current();
                      drop table if exists {self.table_name};
                      create table {self.table_name}(a int,  b int);
                      insert into {self.table_name} values(1,2);
                      select pg_sleep(100);
                      end;'''
        session1 = ComThread(self.sh_primy.execut_db_sql, args=(sql_cmd,))
        session1.setDaemon(True)

        text_3 = '---step3:会话2通过系统表查询transaction_id,expect:成功---'
        self.logger.info(text_3)
        select_cmd = f'''select pg_sleep(60);
            select transaction_id, query from statement_history \
            where query like 'drop table if exists {self.table_name}%';
            select transaction_id, query from statement_history \
            where query like 'create table {self.table_name}%';
            select transaction_id, query from statement_history \
            where query like 'insert into {self.table_name}%';'''
        session2 = ComThread(self.sh_primy.execut_db_sql,
                             args=(select_cmd, '', 'postgres',))
        session2.setDaemon(True)
        session1.start()
        session2.start()
        session1.join(120)
        session2.join(120)
        result1 = session1.get_result()
        self.logger.info(result1)
        txid_current_res = result1.splitlines()[4].strip()
        result2 = session2.get_result()
        self.logger.info(result2)
        self.assertIn(self.constant.SET_SUCCESS_MSG and
                      self.constant.START_TRANSACTION_SUCCESS_MSG and
                      self.constant.DROP_TABLE_SUCCESS and
                      self.constant.CREATE_TABLE_SUCCESS and
                      self.constant.INSERT_SUCCESS_MSG,
                      result1, '执行失败:' + text_2)
        select_assert = result2.count(txid_current_res) == 3
        self.assertTrue(select_assert, '执行失败:' + text_3)

    def tearDown(self):
        text = '---step4: 环境清理,expect:成功:---'
        self.logger.info(text)
        drop_cmd = f'drop table {self.table_name};'
        drop_msg = self.sh_primy.execut_db_sql(drop_cmd)
        self.logger.info(drop_msg)
        self.logger.info(
            '----检查参数，恢复默认配置:rack_stmt_stat_level----')
        check_level_res = self.sh_primy.execut_db_sql(self.show_level_cmd)
        self.logger.info(check_level_res)
        current = check_level_res.splitlines()[-2].strip()
        if self.level_default != current:
            result = self.sh_primy.execute_gsguc('reload',
                                                 self.constant.GSGUC_SUCCESS_MSG,
                                                 f"{self.config_level}='{self.level_default}'")
            self.assertTrue(result, '参数恢复失败')
        show_level_msg = self.sh_primy.execut_db_sql(self.show_level_cmd)
        self.logger.info(show_level_msg)
        self.common.equal_sql_mdg(show_level_msg, f'{self.config_level}',
                                  f'{self.level_default}', '(1 row)', flag='1')
        self.assertIn(self.constant.DROP_TABLE_SUCCESS,
                      drop_msg, '执行失败:' + text)
        self.logger.info(
            '---Opengauss_Function_Fullsql_Case0008 finish---')
